package com.example.magical.normal.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.example.magical.normal.dao.CashaMainMapper;
import com.example.magical.normal.domain.CashaMain;
import com.example.magical.normal.service.CashaMainService;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StopWatch;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author weiqi
 * @date 2022年11月29日
 */
@Service
@Slf4j
public class CashaMainServiceImpl implements CashaMainService {
    @Autowired
    private CashaMainMapper cashaMainMapper;


    @Override
    @Transactional(propagation = Propagation.SUPPORTS, rollbackFor = Throwable.class)
    public void manualCheck() {

        List<Integer> tatal = new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            tatal.add(i + 1);
        }
        cashaMainMapper.delete(Wrappers.emptyWrapper());
        tatal.parallelStream().forEach(i -> {
            CashaMain cashaMain = new CashaMain();
            cashaMain.setStoreCode("T" + i);
            cashaMain.setBizDate(new Date());
            cashaMain.setSavingDate(new Date());
            cashaMain.setSavingConfirmDate(new Date());
            cashaMain.setSavingType(3);
            cashaMain.setNeedCasha(1);
            cashaMain.setMustSaveAmount(BigDecimal.TEN);
            cashaMainMapper.insert(cashaMain);
        });


    }

    public static void main(String[] args) {
//        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
//        LocalDate currentMonthDate = LocalDate.now();
//        LocalDate lastMonthDate = currentMonthDate.minusMonths(1L);
//        String startDateStr = lastMonthDate.with(TemporalAdjusters.firstDayOfMonth()).format(formatter);
//        String endDateStr = currentMonthDate.format(formatter);
//        System.out.println(startDateStr);
//        System.out.println("endDateStr = " + endDateStr);

//        Boolean result = new BigDecimal("-55").abs().compareTo(new BigDecimal("-55.00"))==0;
//        System.out.println("result = " + result);

        List<Integer> financeOrderKeyList = new ArrayList<>();
        for (int i = 1; i < 800000; i++) {
            financeOrderKeyList.add(i);
        }
//        List<Integer> syncDataList = Collections.synchronizedList(new ArrayList<>());
        List<Integer> syncDataList = new ArrayList<>();
        ExecutorService executorService = new ThreadPoolExecutor(20, 20, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());

//        ExecutorService executorService = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors() * 2,
//                Runtime.getRuntime().availableProcessors() * 2, 10L, TimeUnit.SECONDS,
//                new LinkedBlockingQueue<>(financeOrderKeyList.size()), new CustomizableThreadFactory( "test-"), new ThreadPoolExecutor.AbortPolicy());
        StopWatch stopWatch = new StopWatch("测试");
        stopWatch.start("test");
        List<List<Integer>> lists = Lists.partition(financeOrderKeyList, 100);
        CompletableFuture[] futures = lists.stream().map(items -> CompletableFuture.runAsync(() -> {
            log.info("线程" + Thread.currentThread().getName());
            for (int i = 0; i < items.size(); i++) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                syncDataList.add(i);
            }
        }, executorService)).toArray(CompletableFuture[]::new);
        CompletableFuture.allOf(futures).join();
        stopWatch.stop();
        log.info(stopWatch.prettyPrint());
        log.info("syncDataList = {}", syncDataList.size());

    }
}
